<?php

/*Google Sitemaps for SMF is written by SMF and modified by Davilac (http://www.davilac.net) 
There's no warranty and no support as is released for free. 
This Sitemaps makes a sitemap with all forum's URL (giving them highest priority), all topics in your forum
(up to 20.000 topics, as Google Sitemaps accept up to 30.000 urls per sitemap) sorted by popularity and also 
includes up to 200 most active users. Also this mod detects if you have short URLS or not. If you have it, 
this script will use it in the sitemap, if not, it will use PHP URLS.
*/

/* Modified to work with the pretty urls mod. For more info see http://code.google.com/p/smf-pretty-sitemap/
 * The top posters sections are commented out, uncomment if you would like to use it. */

require_once('SSI.php');

if ($modSettings['smfVersion'] < '1.1')
	ob_start('ob_sessrewrite');

/* header('Content-Type: text/plain'); */
header('Content-Type: application/xml; charset=UTF-8');

echo '<?xml version="1.0" encoding="UTF-8"?' . '>
<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">';

// Fetch latest posts
$request = db_query("
	SELECT posterTime
	FROM {$db_prefix}messages
	WHERE ID_MSG >= " . ($modSettings['maxMsgID'] - 30) . "
	ORDER BY ID_MSG DESC
	LIMIT 10", __FILE__, __LINE__);
$latest_post_times = array(time());
while ($row = mysql_fetch_assoc($request))
	$latest_post_times[] = $row['posterTime'];
mysql_free_result($request);

// Fetch boards
$request = db_query("
	SELECT ID_BOARD
	FROM {$db_prefix}boards", __FILE__, __LINE__);
$boards = array();
while ($row = mysql_fetch_assoc($request))
{
	$request2 = db_query("
		SELECT posterTime
		FROM {$db_prefix}messages
		WHERE ID_BOARD = $row[ID_BOARD]" . ($modSettings['totalMessages'] > 100000 ? "
			AND ID_MSG >= " . ($modSettings['maxMsgID'] * 0.5) : '') . "
		ORDER BY ID_MSG DESC
		LIMIT 10", __FILE__, __LINE__);
	$board_post_times = array(time());
	while ($row2 = mysql_fetch_assoc($request2))
		$board_post_times[] = $row2['posterTime'];
	mysql_free_result($request2);

	$boards[] = array(
		'id' => $row['ID_BOARD'],
		'times' => $board_post_times,
	);
}
mysql_free_result($request);

// Fetch topics
$request = db_query("
	SELECT ID_TOPIC, pretty_url, ID_BOARD
	FROM {$db_prefix}topics
	ORDER BY numViews + numReplies DESC
	LIMIT 20000", __FILE__, __LINE__);
$topics = array();
while ($row = mysql_fetch_assoc($request))
{
	$request2 = db_query("
		SELECT posterTime
		FROM {$db_prefix}messages
		WHERE ID_TOPIC = $row[ID_TOPIC]
		ORDER BY ID_MSG DESC
		LIMIT 10", __FILE__, __LINE__);
	$topic_post_times = array(time());
	while ($row2 = mysql_fetch_assoc($request2))
		$topic_post_times[] = $row2['posterTime'];
	mysql_free_result($request2);

	$topics[] = array(
		'id' => $row['ID_TOPIC'],
		'times' => $topic_post_times,
		'pretty_url' => $row['pretty_url'],		
		'board_id' => $row['ID_BOARD'],
	);
}
mysql_free_result($request);

// First, the forum URL.  Highest priority!
if (!isset($modSettings['pretty_root_url']))
	$url_loc = $scripturl;   
elseif (isset($modSettings['pretty_root_url']))
	$url_loc = $modSettings['pretty_root_url'] . '/';  
echo '
	<url>
		<loc>', $url_loc, '</loc>
		<lastmod>', posts_max_time($latest_post_times), '</lastmod>
		<changefreq>', posts_to_freq($latest_post_times), '</changefreq>
		<priority>1.0</priority>
	</url>';

$context = array('pretty' => array());
// Unserialize the array of pretty board URLs
$context['pretty']['board_urls'] = unserialize($modSettings['pretty_board_urls']);

// Now the boards! We must check if the forum is using the default urls, SEF urls or pretty urls.
foreach ($boards as $board) {
    if ($modSettings['queryless_urls']==0 && !isset($modSettings['pretty_root_url']))
	$url_loc = $scripturl.'?board='.$board['id'].'.0';
    elseif ($modSettings['queryless_urls']==1 && !isset($modSettings['pretty_root_url']))
	$url_loc = $scripturl.'/board,'.$board['id'].'.0.html';   
    elseif (isset($modSettings['pretty_root_url']))
	$url_loc = $modSettings['pretty_root_url'] . '/' . (isset($context['pretty']['board_urls'][$board['id']]) ? $context['pretty']['board_urls'][$board['id']] : $board['id']) . '/0/';    
    echo '
	<url>
		<loc>', $url_loc, '</loc>
		<lastmod>', posts_max_time($board['times']), '</lastmod>
		<changefreq>', posts_to_freq($board['times']), '</changefreq>
		<priority>', posts_to_priority(0.7, $board['times']), '</priority>
	</url>';
}

// Popular topics too... 
foreach ($topics as $topic) {
    if ($modSettings['queryless_urls']==0 && !isset($modSettings['pretty_root_url']))
	$url_loc = $scripturl.'?topic='.$topic['id'].'.0';
    elseif ($modSettings['queryless_urls']==1 && !isset($modSettings['pretty_root_url']))
	$url_loc = $scripturl.'/topic,'.$topic['id'].'.0.html';   
    elseif (isset($modSettings['pretty_root_url']))
	$pretty_board = $modSettings['pretty_root_url'] . '/' . (isset($context['pretty']['board_urls'][$topic['board_id']]) ? $context['pretty']['board_urls'][$topic['board_id']] : $topic['board_id']) . '/';
	$url_loc = $pretty_board . (isset($topic['pretty_url']) && $topic['pretty_url'] != '' ? $topic['pretty_url'] : $topic['id']) . '/0/';
	echo '
	<url>
		<loc>', $url_loc, '</loc>
		<lastmod>', posts_max_time($topic['times']), '</lastmod>
		<changefreq>', posts_to_freq($topic['times']), '</changefreq>
		<priority>', posts_to_priority(0.8, $topic['times']), '</priority>
	</url>';
}

/*
// Fetch members
$request = db_query("
	SELECT ID_MEMBER
	FROM {$db_prefix}members
	ORDER BY totalTimeLoggedIn DESC
	LIMIT 200", __FILE__, __LINE__);
$members = array();
while ($row = mysql_fetch_assoc($request))
{
	$request2 = db_query("
		SELECT posterTime
		FROM {$db_prefix}messages
		WHERE ID_MEMBER = $row[ID_MEMBER]" . ($modSettings['totalMessages'] > 100000 ? "
			AND ID_MSG >= " . ($modSettings['maxMsgID'] * 0.5) : '') . "
		ORDER BY ID_MSG DESC
		LIMIT 10", __FILE__, __LINE__);
	$member_post_times = array(time());
	while ($row2 = mysql_fetch_assoc($request2))
		$member_post_times[] = $row2['posterTime'];
	mysql_free_result($request2);

	$members[] = array(
		'id' => $row['ID_MEMBER'],
		'times' => $member_post_times,
	);
}
mysql_free_result($request);

// Most active members?
foreach ($members as $member)
{
	echo '
	<url>
		<loc>', $scripturl, '?action=profile;u=', $member['id'], '</loc>
		<lastmod>', posts_max_time($member['times']), '</lastmod>
		<changefreq>', posts_to_freq($member['times']), '</changefreq>
		<priority>', posts_to_priority(0.3, $board['times']), '</priority>
	</url>';
} */

echo '
</urlset>';

function posts_max_time($post_times) {
	if (empty($post_times) || count($post_times) == 1)
		return gmstrftime('%Y-%m-%dT%H:%M:%S+00:00', time() - 3600 * 24 * 10);

	return gmstrftime('%Y-%m-%dT%H:%M:%S+00:00', max($post_times));
}

function posts_to_priority($base, $post_times) {
	if (empty($post_times) || count($post_times) == 1)
	    return sprintf('%1.1f', $base);

	array_shift($post_times);

	// get avg time between posts
	$postinterval = (max($post_times) - min($post_times)) / count($post_times);
	$timesincepost = time() - max($post_times);

	if ($postinterval < 3600 * 24)
	    $mod = 0.1;
	else
	    $mod = 0;
	if ($timesincepost < 3600 * 48)
	    $mod = $mod + 0.1;

	return sprintf('%1.1f', $base + $mod);
}

function posts_to_freq($post_times) {
	if (empty($post_times) || count($post_times) == 1)
		return 'yearly';

	$s = (max($post_times) - min($post_times)) / count($post_times);

	// Changes more often than every hour.
	if ($s < 3600)
		return 'always';
	elseif ($s < 3600 * 12)
		return 'hourly';
	elseif ($s < 3600 * 24 * 4)
		return 'daily';
	else
		return 'monthly';
}

?>
